import os
import platform
import re
import shutil
import sys
import time
import json
import tkinter
import winreg
import zipfile
import pandas
import requests
import datetime
import operator
from typing import Any
import tkinter.messagebox
from win32com import client
from selenium import webdriver
from tkinter import END, Canvas, Entry, Tk
from selenium.webdriver.common.by import By
from tkinter import Scrollbar, Text, filedialog
from selenium.webdriver.chrome.service import Service
from tkinter.ttk import Combobox, Progressbar, Treeview
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class Log:
    def __init__(self, file: str) -> None:
        try:
            self._stdout = sys.stdout
        except Exception:
            pass
        try:
            self.stdout = open(file, 'ab', buffering=0)
        except Exception:
            pass

    def __del__(self) -> None:
        try:
            self.stdout.close()
        except Exception:
            pass

    def write(self, __s: str) -> None:
        _str = '\n' if __s == '\n' else '%s:\n%s' % (datetime.datetime.now().strftime(r'%Y-%m-%d %H:%M:%S'), __s)
        try:
            self.stdout.write(_str.encode('utf-8'))
        except Exception:
            pass
        try:
            self._stdout.write(_str)
        except Exception:
            pass

    def flush(self) -> None:
        try:
            self.stdout.flush()
        except Exception:
            pass
        try:
            self._stdout.flush()
        except Exception:
            pass

def login(root: str, userName: str, password: str) -> dict[str, str]:
    cookies = ''
    options = webdriver.EdgeOptions()
    options.add_argument('--headless')
    options.add_argument('--mute-audio')
    driver = webdriver.Edge(service=Service('%s/msedgedriver.exe' % (root)), options=options)
    driver.get('https://vms.zyh365.com/login/login.do')
    userNameInput = WebDriverWait(driver, 60, 1).until(EC.presence_of_element_located([By.CSS_SELECTOR, '#loginName']))
    passwordInput = WebDriverWait(driver, 60, 1).until(EC.presence_of_element_located([By.CSS_SELECTOR, '#loginPWD']))
    agreeInput = WebDriverWait(driver, 60, 1).until(EC.presence_of_element_located([By.CSS_SELECTOR, '#xuzhi']))
    loginInput = WebDriverWait(driver, 60, 1).until(EC.presence_of_element_located([By.CSS_SELECTOR, 'input[value="登  录"]']))
    userNameInput.send_keys(userName)
    passwordInput.send_keys(password)
    agreeInput.click()
    loginInput.click()
    while driver.current_url == 'https://vms.zyh365.com/login/login.do':
        time.sleep(1)
    time.sleep(2)
    for item in driver.get_cookies():
        cookies += '%s=%s;' % (item['name'], item['value'])
    return { 'Cookie': cookies[0:-1], 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0' }

def submit(headers: str, id: str, idcard: str, name: str, deptid: str, activityid: str, activitytimes: str, value: str, remark: str) -> dict[str, str]:
    data = { 'id': id, 'idcard': idcard, 'name': name, 'deptid': deptid, 'activityid': activityid, 'activitytimes': activitytimes, 'value': value, 'remark': remark, 'picpath': '' }
    return requests.post('https://vms.zyh365.com/volunteer/his/submit.do', headers=headers, data=data).json()

def getVolunteer(headers: str, vcode: str) -> dict[str, Any]:
    data = { 'vcode': vcode }
    return requests.post('https://vms.zyh365.com/volunteer/list.do', headers=headers, data=data).json()['rows'][0]

def getHonorDurations(headers: str, activityid: str, volunteerid: str, page: str, rows: str) -> dict[str, Any]:
    data = { 'activityid': activityid, 'volunteerid': volunteerid, 'page': page, 'rows': rows, 'sort': '_id', 'order': 'desc' }
    return requests.post('https://vms.zyh365.com/activity/sign/volunteerHisDurationDetail.do', headers=headers, data=data).json()

def getTimes(headers: str, start: str, end: str) -> list[dict[str, str]]:
    data = { 'start': start, 'end': end }
    return requests.post('https://vms.zyh365.com/volunteer/his/timedate.do', headers=headers, data=data).json()

def getDepartments(headers: str) -> list[dict[str, str]]:
    data = {}
    return requests.post('https://vms.zyh365.com/sys/department/userDepartmentList.do', headers=headers, data=data).json()

def getActivitys(headers: str, deptid: str, name: str, page: str, rows: str) -> dict[str, Any]:
    data = { 'deptid': deptid, 'q': name, 'page': page, 'rows': rows, 'sort': '_id', 'order': 'asc' }
    return requests.post('https://vms.zyh365.com/volunteer/his/activitylist.do', headers=headers, data=data).json()

def getAllHonorDurations(headers: str, activityid: str, volunteerid: str) -> list[dict[str, Any]]:
    page = 1
    rows = 50
    response = getHonorDurations(headers, activityid, volunteerid, str(page), str(rows))
    result = list(response['rows'])
    count = int(int(response['total']) / rows)
    for i in range(0, count):
        page += 1
        result +=  getHonorDurations(headers, activityid, volunteerid, str(page), str(rows))['rows']
    return result

def createTable(columns: list[dict[str, Any]]) -> dict[str, Any]:
    ybar = Scrollbar(window, orient='vertical')
    table = Treeview(window, height=15, show='headings', columns=list(map(lambda e: e['name'], columns)), yscrollcommand=ybar.set)
    for item in columns:
        table.heading(item['name'], text=item['name'], anchor='center')
        table.column(item['name'], width=item['width'], anchor='center')
    ybar['command'] = table.yview
    return { 'table': table, 'ybar': ybar }

def search(headers: dict[str, str], deptid: str, activitieName: Entry, activitiePage: Entry) -> list[dict[str, Any]]:
    index = 0
    result = []
    for item in getActivitys(headers, deptid, activitieName, activitiePage, '50')['rows']:
        index += 1
        item['_value'] = '【%d】%s（%s ~ %s）' % (index, item['title'], item['actstarttime'], item['actendtime'])
        result.append(item)
    return result

def selectFile(table: Treeview) -> list[dict[str, Any]]:
    contents = []
    sheet = pandas.read_excel(filedialog.askopenfilename(filetypes=[('excel表格', '*.xlsx')]))
    titles = [{ 'name': '姓名', 'default': '' }, { 'name': '手机号', 'default': '' }, { 'name': '志愿者编号', 'default': '' }, { 'name': '荣誉时数', 'default': 0 }, { 'name': '补录原因', 'default': '' }]
    for item in titles:
        if not(item['name'] in list(sheet.columns)):
            tkinter.messagebox.showerror('提示', '必填列（%s）' % (item['name']))
            return
        sheet.fillna({ item['name']: item['default'] }, inplace=True)
    for item in sheet.values.tolist():
        index = 0
        content = {}
        for head in list(sheet.columns):
            content[head] = item[index]
            index += 1
        contents.append(content)
    for item in table.get_children(''):
        table.delete(item)
    index = 0
    for item in contents:
        table.insert('', index, values=[index + 1] + list(map(lambda e: item[e['name']], titles)))
        index += 1
    return contents

def departmentNameValues(data: list[dict[str, str]]) -> list[str]:
    index = 0
    result = []
    for item in data:
        index += 1
        result.append('【%d】%s' % (index, item['name']))
    return result

def confirm(data: dict[str, Any], table: Treeview, progressbar: Progressbar, target: Text) -> None:
    try:
        times = []
        result = []
        targetIndex = 1
        maxDuration = '0.00'
        _remark = data['remark']
        _value = data['duration']
        deptid = data['department']
        activitytimes = data['time']
        activityid = data['activity']
        tableIds = table.get_children('')
        organizationName = ''
        relatedActivitie = ''
        activityTime = activitytimes
        honorDuration = '%.2f' % (float(_value))
        reasonForSupplementaryRecording = _remark
        for item in data['departments']:
            if item['id'] == deptid:
                organizationName = item['name']
                break
        for item in data['activitys']:
            if item['_id'] == activityid:
                relatedActivitie = item['title']
                break
        if tkinter.messagebox.askquestion('提示', '组织名称：%s\n活动名称：%s\n活动时间：%s\n荣誉时长：%s\n补录原因：%s' % (organizationName, relatedActivitie, activityTime, honorDuration, reasonForSupplementaryRecording)) != 'yes':
            return
        for item in data['activitys']:
            if item['_id'] == activityid:
                maxDuration = '%.2f' % (float(int(time.mktime(time.strptime('%s %s:00' % (item['actstarttime'], item['signendtime']), '%Y-%m-%d %H:%M:%S'))) - int(time.mktime(time.strptime('%s %s:00' % (item['actstarttime'], item['signstarttime']), '%Y-%m-%d %H:%M:%S')))) / 3600)
                maxDuration = maxDuration if float(maxDuration) <= 10 else '10.00'
        for i in range(0, len(data['times'])):
            if data['times'][i]['id'] == activitytimes:
                for item in range(i, len(data['times'])):
                    times.append(data['times'][item]['id'])
                break
        for volunteer in data['volunteers']:
            if float(volunteer['荣誉时数'] if '荣誉时数' in volunteer else _value) > float(len(times) * float(maxDuration)):
                tkinter.messagebox.showinfo('提示', '荣誉时数超额！')
                return
        progressbar['value'] = 0
        progressbar.update()
        table.selection_clear()
        table.update()
        target.configure(state='normal')
        target.delete('0.0', END)
        target.configure(state='disabled')
        target.update()
        for volunteer in data['volunteers']:
            id = ''
            name = ''
            phone = ''
            vcode = ''
            value = ''
            remark = ''
            idcard = ''
            resultFlag = True
            errorMessage = ''
            completionTime = 0.0
            try:
                detail = getVolunteer(data['headers'], volunteer['志愿者编号'] if '志愿者编号' in volunteer else '')
                honorDurations = getAllHonorDurations(data['headers'], activityid, detail['_id'])
                id = detail['_id'] if '_id' in detail else ''
                idcard = detail['idcard'] if 'idcard' in detail else ''
                name = volunteer['姓名'] if '姓名' in volunteer else ''
                phone = volunteer['手机号'] if '手机号' in volunteer else ''
                vcode = volunteer['志愿者编号'] if '志愿者编号' in volunteer else ''
                value = volunteer['荣誉时数'] if '荣誉时数' in volunteer else _value
                remark = volunteer['补录原因'] if '补录原因' in volunteer else _remark
                count = int(float(value) / float(maxDuration)) + 1
                if id == '' or idcard == '' or name == '' or deptid == '' or activityid == '' or activitytimes == '' or float(value) <= 0 or remark == '':
                    tkinter.messagebox.showerror('提示', '数据错误（%d行）' % (targetIndex))
                    raise Exception('数据错误')
                table.selection_set(tableIds[targetIndex - 1])
                table.update()
                target.configure(state='normal')
                target.delete('0.0', END)
                target.insert('0.0', '【%d】%s-%s（%.2f）正在进行...' % (targetIndex, name, phone, float(value)))
                target.configure(state='disabled')
                target.update()
                for i in range(0, count):
                    todayCompletionTime = 0.0
                    currentCompletionTime = 0.0
                    if not(i < len(times)):
                        resultFlag = resultFlag and False
                        errorMessage += '荣誉时数超额\n'
                        break
                    for honorDuration in honorDurations:
                        if honorDuration['actdate'] == times[i]:
                            todayCompletionTime += float(honorDuration['value'])
                    currentMaxDuration = float(maxDuration) - float(todayCompletionTime)
                    if i != count - 1:
                        currentCompletionTime = float(maxDuration) if float(currentMaxDuration) >= (maxDuration) else float(currentMaxDuration)
                    else:
                        lastTime = float(value) - i * float(maxDuration)
                        currentCompletionTime = float(currentMaxDuration) if float(lastTime) >= float(currentMaxDuration) else float(lastTime)
                    if submit(data['headers'], id, idcard, name, deptid, activityid, times[i], '%.2f' % (currentCompletionTime), remark)['message'] == '调用成功':
                        resultFlag = resultFlag and True
                        completionTime += currentCompletionTime
                    else: 
                        resultFlag = resultFlag and False
                        errorMessage += '补录时间：%s 补录时长：%.2f\n' % (times[i], currentCompletionTime)
                    time.sleep(1)
                progressbar['value'] = int(targetIndex / len(data['volunteers']) * 100)
                progressbar.update()
            except Exception as error:
                print(error)
                tkinter.messagebox.showerror('提示', '异常（%d行）' % targetIndex)
            finally:
                result.append([name, phone, vcode, value, '%.2f' % (completionTime), remark, '成功' if resultFlag else '失败', errorMessage])
                print('id:%s,idcard:%s,name:%s,phone:%s,deptid:%s,activityid:%s,activitytimes:%s,value:%s,completionTime:%.2f,remark:%s,result:%s,errorMessage:%s' % (id, idcard, name, phone, deptid, activityid, activitytimes, value, completionTime, remark, '成功' if resultFlag else '失败', errorMessage))
                targetIndex += 1
        progressbar['value'] = 100
        progressbar.update()
        table.selection_clear()
        table.update()
        target.configure(state='normal')
        target.delete('0.0', END)
        target.configure(state='disabled')
        target.update()
        tkinter.messagebox.showinfo('提示', '请选择结果文件保存路径')
        pandas.DataFrame(result, columns=['姓名', '手机号', '志愿者编号', '荣誉时数', '完成荣誉时长', '补录原因', '结果', '失败信息']).to_excel('%s/补录结果-%d.xlsx' % (filedialog.askdirectory(), time.time()), sheet_name='Sheet1', index=False)
        tkinter.messagebox.showinfo('提示', '保存成功')
    except Exception as error:
        print(error)
        tkinter.messagebox.showerror('提示', '异常')

data = {
    'stdout': None,
    'headers': {},
    'time': '',
    'remark': '',
    'activity': '',
    'duration': '',
    'department': '',
    'times': [],
    'activitys': [],
    'volunteers': [],
    'departments': [],
    'userName': '',
    'password': '',
    'rootPath': '.'
}

try:
    [platformBit, _] = platform.architecture()
    [msedgeVersion, _] = winreg.QueryValueEx(winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Edge\BLBeacon'), 'version')
    print('正在检查网络...')
    while os.system('ping bing.com -n 1') != 0:
        print('网络未连接！')
        time.sleep(1)
    print('网络连接成功！')
    print('正在检查驱动...')
    if not(os.path.exists('./msedgedriver.exe')) or msedgeVersion != client.Dispatch('Scripting.FileSystemObject').GetFileVersion('./msedgedriver.exe'):
        print('开始安装msedgedriver version:%s' % msedgeVersion)
        msedgedriver = requests.get('https://msedgedriver.azureedge.net/%s/edgedriver_%s.zip' % (msedgeVersion, 'win64' if platformBit == '64Bit' else 'win32'))
        with open('./msedgedriver.zip','wb') as file:
            file.write(msedgedriver.content)
        with zipfile.ZipFile('./msedgedriver.zip') as file:
            file.extractall('./msedgedriver')
        os.remove('./msedgedriver.zip')
        shutil.copy('./msedgedriver/msedgedriver.exe', './msedgedriver.exe')
        shutil.rmtree('./msedgedriver')
        print('msedgedriver version:%s安装成功！' % msedgeVersion)
    print('驱动检查成功！')
except Exception as error:
    print(error)
    tkinter.messagebox.showerror('提示', '更新异常')
    sys.exit(0)

try:
    def loginSubmit(root: Tk, data: dict[str, Any], userName: str, password: str) -> None:
        if re.match(r'^[0-9]{18}$', userName) == None:
            tkinter.messagebox.showerror('提示', '账号格式错误！')
            return
        if re.match(r'^[_-~!@#$%^&*0-9a-zA-Z]{8,20}$', password) == None:
            tkinter.messagebox.showerror('提示', '密码格式错误！')
            return
        data['userName'] = userName
        data['password'] = password
        file = open('%s/data/user.json' % (data['rootPath']), 'w', encoding='utf-8')
        file.write(json.dumps({ 'userName': data['userName'], 'password': data['password'] }, ensure_ascii=False, indent=4))
        file.close()
        root.destroy()
    data['rootPath'] = os.getcwd()
    if not(os.path.exists('%s/data' % (data['rootPath']))):
        os.makedirs('%s/data' % (data['rootPath']))
        print('%s/data 创建成功！' % (data['rootPath']))
    if not(os.access('%s/data/log.txt' % (data['rootPath']), os.F_OK)):
        file = open('%s/data/log.txt' % (data['rootPath']), 'w', encoding='utf-8')
        file.close()
        print('%s/data/log.txt 创建成功！' % (data['rootPath']))
    if not(os.access('%s/data/user.json' % (data['rootPath']), os.F_OK)):
        file = open('%s/data/user.json' % (data['rootPath']), 'w', encoding='utf-8')
        file.write(json.dumps({ 'userName': '', 'password': '' }, ensure_ascii=False, indent=4))
        file.close()
        print('%s/data/user.json 创建成功！' % (data['rootPath']))

    data['stdout'] = sys.stdout
    sys.stdout = Log('%s/data/log.txt' % (data['rootPath']))

    file = open('%s/data/user.json' % (data['rootPath']), 'r', encoding='utf-8')
    user = json.loads(file.read())
    file.close()

    dialog = tkinter.Tk()
    clientWidth = 300
    clientHeight = 150
    dialog.title('登录')
    dialog.resizable(0, 0)
    dialog.iconbitmap('%s/data/logo.ico' % data['rootPath'])
    dialog.protocol('WM_DELETE_WINDOW', lambda: (dialog.destroy(), sys.exit(0)))
    dialog.geometry('%dx%d+%d+%d' % (clientWidth, clientHeight, dialog.winfo_screenwidth() / 2 - clientWidth / 2, dialog.winfo_screenheight() / 2 - clientHeight / 2))

    label1 = tkinter.Label(dialog, text='账号')
    input1 = tkinter.Entry(dialog, width=35)
    label2 = tkinter.Label(dialog, text='密码')
    input2 = tkinter.Entry(dialog, show='*', width=35)
    loginSubmitInput = tkinter.Button(dialog, text='登录', width=20, command=lambda: loginSubmit(dialog, data, input1.get(), input2.get()))
    canvas = Canvas(dialog, width=280, height=42)

    input1.insert(0, user['userName'])
    input2.insert(0, user['password'])
    canvas.create_text(140, 10, text='开发者：“五彩湖工”青年志愿者中心2023-2024届主席', font="宋体 8")

    label1.grid(row=1, column=1, padx=5, pady=5)
    input1.grid(row=1, column=2, padx=5, pady=5)
    label2.grid(row=2, column=1, padx=5, pady=5)
    input2.grid(row=2, column=2, padx=5, pady=5)
    loginSubmitInput.grid(row=3, column=1, padx=5, pady=5, columnspan=2)
    canvas.grid(row=4, column=1, padx=5, pady=5, columnspan=2)

    dialog.lift()
    dialog.mainloop()
except Exception as error:
    print(error)
    tkinter.messagebox.showerror('提示', '异常')
    sys.exit(0)

try:
    window = tkinter.Tk()
    clientWidth = 800
    clientHeight = 600
    window.resizable(0, 0)
    window.title('"五彩湖工"青年志愿者中心（志愿汇荣誉时长）-lwl')
    window.iconbitmap('%s/data/logo.ico' % data['rootPath'])
    window.geometry('%dx%d+%d+%d' % (clientWidth, clientHeight, window.winfo_screenwidth() / 2 - clientWidth / 2, window.winfo_screenheight() / 2 - clientHeight / 2))

    isUIntValidate = window.register(lambda e: re.match(r'^[0-9]+$', e) != None)
    isTwoDecimalValidate = window.register(lambda e: re.match(r'^[0-9]+\.[0-9]{2}$', e) != None)

    label1 = tkinter.Label(window, text='组织名称')
    input1 = Combobox(window, width=20, state='readonly', values=[])
    label2 = tkinter.Label(window, text='活动名称')
    input2 = tkinter.Entry(window)
    label3 = tkinter.Label(window, text='查看页码')
    input3 = tkinter.Entry(window, validate='focusout', validatecommand=(isUIntValidate, '%P'), invalidcommand=lambda: (input3.delete(0, END), input3.insert(0, '1')))
    label4 = tkinter.Label(window, text='关联活动')
    input4 = Combobox(window, width=85, state='readonly', values=[])
    label5 = tkinter.Label(window, text='活动时间')
    input5 = Combobox(window, width=20, state='readonly', values=[])
    label6 = tkinter.Label(window, text='荣誉时长')
    input6 = tkinter.Entry(window, validate='focusout', validatecommand=(isTwoDecimalValidate, '%P'), invalidcommand=lambda: (input6.delete(0, END), input6.insert(0, '0.00')))
    label7 = tkinter.Label(window, text='补录原因')
    input7 = tkinter.Entry(window)
    label8 = tkinter.Label(window, text='补录名单')
    input8 = tkinter.Button(window, text='选择文件', command=lambda: operator.setitem(data, 'volunteers', selectFile(table1['table'])))
    label9 = tkinter.Label(window, text='补录信息')
    input9 = tkinter.Text(window, width=50, height=1, state='disabled')
    label10 = tkinter.Label(window, text='补录进度') 
    input10 = Progressbar(window, length=600, value=0)
    searchInput = tkinter.Button(window, text='搜索', command=lambda: (operator.setitem(data, 'activitys', search(data['headers'], data['department'], input2.get(), input3.get())), input4.configure(state='normal'), input4.delete(0, END), input4.configure(state='readonly'), operator.setitem(input4, 'values', list(map(lambda e: e['_value'], data['activitys'])))))
    submitInput = tkinter.Button(window, text='确认', command=lambda: confirm(data, table1['table'], input10, input9))
    table1 = createTable([{ 'name': '序号',  'width': 50 }, { 'name': '姓名',  'width': 120 }, { 'name': '手机号',  'width': 120 }, { 'name': '志愿者编号',  'width': 180 }, { 'name': '荣誉时数',  'width': 80 }, { 'name': '补录原因',  'width': 150 }])

    input1.bind('<<ComboboxSelected>>', lambda event: operator.setitem(data, 'department', data['departments'][int(re.match(r'^【[0-9]+】', input1.get())[0][1:-1]) - 1]['id']))
    input4.bind('<<ComboboxSelected>>', lambda event: (operator.setitem(data, 'activity', data['activitys'][int(re.match(r'^【[0-9]+】', input4.get())[0][1:-1]) - 1]['_id']), operator.setitem(data, 'times', getTimes(data['headers'], data['activitys'][int(re.match(r'^【[0-9]+】', input4.get())[0][1:-1]) - 1]['actstarttime'], data['activitys'][int(re.match(r'^【[0-9]+】', input4.get())[0][1:-1]) - 1]['actendtime'])), input5.configure(state='normal'), input5.delete(0, END), input5.configure(state='readonly'), operator.setitem(input5, 'values', list(map(lambda e: e['id'], data['times'])))))
    input5.bind('<<ComboboxSelected>>', lambda event: operator.setitem(data, 'time', input5.get()))
    input6.bind('<FocusOut>', lambda event: operator.setitem(data, 'duration', input6.get()))
    input7.bind('<FocusOut>', lambda event: operator.setitem(data, 'remark', input7.get()))

    label1.grid(row=1, column=1, padx=10, pady=10)
    input1.grid(row=1, column=2, padx=10, pady=10)
    label2.grid(row=1, column=3, padx=10, pady=10)
    input2.grid(row=1, column=4, padx=10, pady=10)
    label3.grid(row=1, column=5, padx=10, pady=10)
    input3.grid(row=1, column=6, padx=10, pady=10)
    searchInput.grid(row=1, column=7, padx=10, pady=10)

    label4.grid(row=2, column=1, padx=10, pady=10)
    input4.grid(row=2, column=2, padx=10, pady=10, columnspan=6)

    label5.grid(row=3, column=1, padx=10, pady=10)
    input5.grid(row=3, column=2, padx=10, pady=10)
    label6.grid(row=3, column=3, padx=10, pady=10)
    input6.grid(row=3, column=4, padx=10, pady=10)
    label7.grid(row=3, column=5, padx=10, pady=10)
    input7.grid(row=3, column=6, padx=10, pady=10)

    label8.grid(row=4, column=1, padx=10, pady=10)
    input8.grid(row=4, column=2, padx=10, pady=10)
    label9.grid(row=4, column=3, padx=10, pady=10)
    input9.grid(row=4, column=4, padx=10, pady=10, columnspan=3)
    submitInput.grid(row=4, column=7, padx=10, pady=10)

    table1['table'].grid(row=5, column=1, padx=10, pady=10, columnspan=7)
    table1['ybar'].grid(row=5, column=7, sticky='ns')

    label10.grid(row=6, column=1, padx=10, pady=10)
    input10.grid(row=6, column=2, padx=10, pady=10, columnspan=5)

    data['headers'] = login(data['rootPath'], data['userName'], data['password'])
    data['departments'] = getDepartments(data['headers'])
    input1['values'] = departmentNameValues(data['departments'])

    window.lift()
    window.mainloop()
except Exception as error:
    print(error)
    tkinter.messagebox.showerror('提示', '异常')
    sys.exit(0)